﻿using System;
using System.Collections.Generic;

namespace JESAI.Core.Data;

/// <summary>具有可读写的扩展数据</summary>
/// <remarks>
/// 仅限于扩展属性，不包括基本属性，区别于 IModel
/// </remarks>
public interface IExtend
{
    /// <summary>数据项</summary>
    IDictionary<String, Object> Items { get; }

    /// <summary>设置 或 获取 数据项</summary>
    /// <param name="key"></param>
    /// <returns></returns>
    Object this[String key] { get; set; }
}

/// <summary>具有扩展数据字典</summary>
/// <remarks>
/// 仅限于扩展属性，不包括基本属性
/// </remarks>
[Obsolete("逐步取消 IExtend2")]
public interface IExtend2 : IExtend
{
    /// <summary>扩展数据键集合</summary>
    IEnumerable<String> Keys { get; }
}

/// <summary>具有扩展数据字典</summary>
/// <remarks>
/// 仅限于扩展属性，不包括基本属性
/// </remarks>
[Obsolete("逐步取消 IExtend3")]
public interface IExtend3 : IExtend
{
}

///// <summary>扩展数据助手</summary>
//public static class ExtendHelper
//{
//    /// <summary>名值字典转扩展接口</summary>
//    /// <param name="dictionary">字典</param>
//    /// <returns></returns>
//    public static IExtend ToExtend(this IDictionary<String, Object> dictionary)
//    {
//        if (dictionary is IExtend ext) return ext;

//        return new ExtendDictionary { Items = dictionary };
//    }

//    /// <summary>扩展接口转名值字典</summary>
//    /// <remarks>
//    /// 需要注意，还有一个 Object.ToDictionary() 扩展，位于 CollectionHelper
//    /// </remarks>
//    /// <param name="extend">扩展对象</param>
//    /// <returns></returns>
//    public static IDictionary<String, Object> ToDictionary(this IExtend extend)
//    {
//        if (extend == null) return null;

//        // 泛型字典
//        if (extend is IDictionary<String, Object> dictionary) return dictionary;
//        if (extend is ExtendDictionary edic) return edic.Items;
//        if (extend is IExtend3 ext3) return ext3.Items;

//        //// IExtend2
//        //if (extend is IExtend2 ext2 && ext2.Keys != null)
//        //{
//        //    var dic = new Dictionary<String, Object>();
//        //    foreach (var item in ext2.Keys)
//        //    {
//        //        dic[item] = extend[item];
//        //    }
//        //    return dic;
//        //}

//        // 普通字典
//        if (extend is IDictionary dictionary2)
//        {
//            var dic = new Dictionary<String, Object>();
//            foreach (DictionaryEntry item in dictionary2)
//            {
//                dic[item.Key + ""] = item.Value;
//            }
//            return dic;
//        }

//        // 反射 Items
//        var pis = extend.GetType().GetProperties(true);
//        var pi = pis.FirstOrDefault(e => e.Name == "Items");
//        if (pi != null && pi.PropertyType.As<IDictionary<String, Object>>()) return pi.GetValue(extend, null) as IDictionary<String, Object>;

//        // 反射属性
//        return new ExtendDictionary2 { Data = extend, Keys = pis.Select(e => e.Name).ToList() };

//        //var dic2 = new Dictionary<String, Object>();
//        //foreach (var item in pis)
//        //{
//        //    dic2[item.Name] = extend[item.Name];
//        //}

//        //return dic2;
//    }

//    /// <summary>从源对象拷贝数据到目标对象</summary>
//    /// <param name="target">目标对象</param>
//    /// <param name="source">源对象</param>
//    public static void Copy(this IExtend target, IExtend source)
//    {
//        var dst = target.ToDictionary();
//        var src = source.ToDictionary();
//        foreach (var item in src)
//        {
//            if (dst.ContainsKey(item.Key)) dst[item.Key] = item.Value;
//        }
//    }
//}

///// <summary>扩展字典。引用型</summary>
//public class ExtendDictionary : IExtend, /*IExtend2,*/ IExtend3
//{
//    /// <summary>数据项</summary>
//    public IDictionary<String, Object> Items { get; set; }

//    //IEnumerable<String> IExtend2.Keys => Items?.Keys;

//    /// <summary>获取 或 设置 数据</summary>
//    /// <param name="item"></param>
//    /// <returns></returns>
//    public Object this[String item]
//    {
//        get
//        {
//            if (Items == null) return null;

//            if (Items.TryGetValue(item, out var v)) return v;

//            return default;
//        }
//        set
//        {
//            if (Items == null) Items = new Dictionary<String, Object>();

//            Items[item] = value;
//        }
//    }
//}

//internal class ExtendDictionary2 : IDictionary<String, Object>
//{
//    public IExtend Data { get; set; }

//    public ICollection<String> Keys { get; set; }

//    public Object this[String key] { get => Data[key]; set => Data[key] = value; }

//    public ICollection<Object> Values => Keys.Select(e => Data[e]).ToList();

//    public Int32 Count => Keys.Count;

//    public Boolean IsReadOnly => false;

//    public void Add(String key, Object value) => throw new NotImplementedException();

//    public void Add(KeyValuePair<String, Object> item) => throw new NotImplementedException();

//    public void Clear() => throw new NotImplementedException();

//    public Boolean Contains(KeyValuePair<String, Object> item) => Keys.Contains(item.Key);

//    public Boolean ContainsKey(String key) => Keys.Contains(key);

//    public void CopyTo(KeyValuePair<String, Object>[] array, Int32 arrayIndex) => throw new NotImplementedException();

//    public IEnumerator<KeyValuePair<String, Object>> GetEnumerator()
//    {
//        foreach (var item in Keys)
//        {
//            yield return new KeyValuePair<String, Object>(item, Data[item]);
//        }
//    }

//    public Boolean Remove(String key) => throw new NotImplementedException();

//    public Boolean Remove(KeyValuePair<String, Object> item) => throw new NotImplementedException();

//    public Boolean TryGetValue(String key, out Object value)
//    {
//        if (Keys.Contains(key))
//        {
//            value = Data[key];
//            return true;
//        }
//        else
//        {
//            value = null;
//            return false;
//        }
//    }

//    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
//}